/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package byblos.apresentacao.site;

import byblos.apresentacao.idioma.InterceptadorIdioma;
import byblos.negocio.Idioma;
import byblos.negocio.NegocioExcecao;
import byblos.negocio.acomodacao.CategoriaAcomodacao;
import byblos.negocio.acomodacao.TipoAcomodacao;
import byblos.negocio.pacote.Pacote;
import byblos.negocio.pacote.PacoteAberto;
import byblos.negocio.pacote.PacoteFechado;
import byblos.negocio.reserva.Reserva;
import byblos.negocio.reserva.prereserva.PreReserva;
import byblos.persistencia.DAO;
import java.util.Calendar;
import java.util.List;
import org.vraptor.annotations.Component;
import org.vraptor.annotations.In;
import org.vraptor.annotations.InterceptedBy;
import org.vraptor.annotations.Logic;
import org.vraptor.annotations.Out;
import org.vraptor.annotations.Parameter;

/**
 *
 * @author Administrador
 */
@Component
@InterceptedBy(value = InterceptadorIdioma.class)
public class SiteReservaComponent {

    @In
    private Idioma idioma;
    @Out
    private Pacote pacote;
    @Out
    private List<Pacote> pacotes;
    //Pacote Aberto ou Avulso
    @Parameter
    private Calendar dataCheckin;
    @Out
    @Parameter
    private TipoAcomodacao tipoAcomodacao;
    //Avulso
    @Out
    @Parameter
    private int numeroNoites;
    @Out
    private String periodoHospedagem;
    @Out
    private String checkin;    //verTarifa
    @Out
    private List<CategoriaAcomodacao> categorias;
    @Parameter
    private Integer pacoteId;
    @Out
    private List<Reserva> reservas;
    @Out
    private boolean isPacote;

    public void verTarifa() {
        pacotes = new DAO().listar(Pacote.class, "PacotePorIdioma", idioma);
        categorias = new DAO().listar(CategoriaAcomodacao.class);
    }

    @Logic(parameters = {"id"})
    public void verTarifaPacote(int id) {
        pacote = new DAO().localizar(Pacote.class, id);
        pacotes = new DAO().listar(Pacote.class, "PacotePorIdioma", pacote.getIdioma());
        pacotes.remove(pacote);
    }

    public void novaReserva() {
        pacotes = new DAO().listar(Pacote.class, "PacotePorIdioma", idioma);
        System.out.println("tipoAcomodacao " + tipoAcomodacao);
        PreReserva preReserva;
        isPacote = pacoteId != null;
        if (isPacote) {
            pacote = new DAO().localizar(Pacote.class, pacoteId);
            pacotes.remove(pacote);
            switch (pacote.getTipoPacote()) {
                case ABERTO:
                    preReserva = new PreReservaPacoteAberto(tipoAcomodacao, dataCheckin, (PacoteAberto) pacote);
                    break;
                case FECHADO:
                    preReserva = new PreReservaPacoteFechado(tipoAcomodacao, (PacoteFechado) pacote);
                    break;
                default:
                    throw new NegocioExcecao("Não foi possível definir o tipo do pacote!");
            }
        } else {
            preReserva = new PreReservaAvulsa(tipoAcomodacao, dataCheckin, numeroNoites);
        }
        reservas = preReserva.getReservas();
        checkin = preReserva.getStringCheckin();
        periodoHospedagem = preReserva.getStringPeriodoHospedagem();
        numeroNoites = preReserva.getNumeroNoites();
    }

    private abstract class PreReservaPeriodoAberto extends PreReserva {

        Calendar dataCheckin;

        public PreReservaPeriodoAberto(TipoAcomodacao tipoAcomodacao, Calendar dataCheckin) {
            super(tipoAcomodacao);
            this.dataCheckin = dataCheckin;
        }

        @Override
        public Calendar getCheckin() {
            return dataCheckin;
        }
    }

    private class PreReservaAvulsa extends PreReservaPeriodoAberto {

        int numeroNoites;

        public PreReservaAvulsa(TipoAcomodacao tipo, Calendar dataCheckin, int numeroNoites) {
            super(tipo, dataCheckin);
            this.numeroNoites = numeroNoites;
        }

        @Override
        public int getNumeroNoites() {
            return numeroNoites;
        }
    }

    private class PreReservaPacoteAberto extends PreReservaPeriodoAberto {

        PacoteAberto pacote;

        public PreReservaPacoteAberto(TipoAcomodacao tipoAcomodacao, Calendar dataCheckin, PacoteAberto pacote) {
            super(tipoAcomodacao, dataCheckin);
            this.pacote = pacote;
        }

        @Override
        public int getNumeroNoites() {
            return pacote.getNumeroNoites();
        }

        @Override
        public Pacote getPacote() {
            return pacote;
        }
    }

    private class PreReservaPacoteFechado extends PreReserva {

        PacoteFechado pacote;

        public PreReservaPacoteFechado(TipoAcomodacao tipoAcomodacao, PacoteFechado pacote) {
            super(tipoAcomodacao);
            this.pacote = pacote;
        }

        @Override
        public Calendar getCheckin() {
            return pacote.getCheckin();
        }

        @Override
        public int getNumeroNoites() {
            return pacote.getNumeroNoites();
        }

        @Override
        public Pacote getPacote() {
            return pacote;
        }
    }
}
